#include<stdio.h>
#include<stdlib.h>
/*定义用到的常量*/
unsigned int A = 0x67452301, B = 0xEFCDAB89, C = 0x98BADCFE, D = 0x10325476, E = 0xC3D2E1F0;        //第一次迭代的链接变量
unsigned int K[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};                              //循环中用到的常量
unsigned int A0 = 0x67452301,B0 = 0xEFCDAB89,C0 = 0x98BADCFE,D0 = 0x10325476,E0 = 0xC3D2E1F0;
/*字节转字*/
int CharToWord(unsigned char *character, int first)
{
	return (((int)character[first] & 0x000000ff) << 24) | (((int)character[first + 1] & 0x000000ff) << 16) | (((int)character[first + 2] & 0x000000ff) << 8) | ((int)character[first + 3] & 0x000000ff);
}
/*f函数*/
unsigned int f(int B, int C, int D, int t)
{
	return (t >= 0 && t <= 19) ? ((B&C) | (~B&D)) : ((t >= 20 && t <= 39) ? (B ^ C ^ D) : ((t >= 40 && t <= 59) ? ((B&C) | (B&D) | (C&D)) : ((t >= 60 && t <= 79) ? B ^ C ^ D : 0)));
}

/*从W消息分组中导出*/
void GetExtraMessage(unsigned int w[])
{
	for (int i = 16; i < 80; w[i++] = ((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) << 1) | ((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) >> 31));
}

/*分组*/
void DevideToGroup(unsigned char *plaintext,unsigned int *group,int length)
{
	int temp = length / 4, l = length,k;
	printf("\n————分组成功！！！\n");
	while (l > 0)
	{
		if (l / 4)
		{
			for (int j = 0; j < temp; j++, l -= 4)
			{
				group[j] = CharToWord(plaintext, 4 * j);
				printf("第%2d组明文是0x%08X\n", j + 1, group[j]);
			}
		}
		else
		{
			plaintext[temp * 4 + (l + 4) % 4] = 0x80;
			for (int k = temp * 4 + (l + 4) % 4 + 1; k < (temp + 1) * 4 - 1; plaintext[k] = 0, k++);
			group[temp] = CharToWord(plaintext, temp * 4);
			printf("第%2d组明文是0x%08X\n", temp + 1, group[temp] = CharToWord(plaintext, temp * 4));
			break;
		}
	}
	for (k = temp + 1; k < 15; group[k++] = 0)
		printf("第%2d组明文是0x%08X\n", k + 1, group[k]);
	printf("第%2d组明文是0x%08X\n", k + 1, group[k]);
}
unsigned int GetK(int t)
{
	return (t >= 0 && t <= 19) ? K[0] : ((t >= 20 && t <= 39) ? K[1] : ((t >= 40 && t <= 59) ? K[2] : ((t >= 60 && t <= 79) ? K[3] : 0)));
}
/*步函数*/
unsigned int StepFunction(unsigned int w[],int t)
{
	unsigned int temp = ((A << 5)|(A >> 27)) + f(B, C, D, t) + E + w[t] + GetK(t);
	E = D,D = C,C = ((B << 30) | (B >> 2)),B = A,A = temp;
	printf("第%2d轮加密后的密文是%08X %08X %08X %08X %08X\n", t + 1, A, B, C, D, E);
}
/*密文组合*/
unsigned int CombineCipher(unsigned int cipher[])
{
	for (int i = 0; i <= 4; i == 0 ? cipher[i] = (A0 + A) : (i == 1 ? cipher[i] = (B0 + B) : (i == 2 ? cipher[i] = (C0 + C) : (i == 3 ? cipher[i] = (D0 + D) : (i == 4 ? cipher[i] = (E0 + E) : 0)))), i++);
}
int main()
{
	int i, t, j, length, temp;
	unsigned char plaintext[64] = "iscbupt", hash[20] = { 0 };
	unsigned int group[80] = { 0 }, cipher[5] = { 0 };
	/*长度填充到最后*/
	printf("当前明文字符串为：");
	for (i = 0; plaintext[i]; length = i + 1,i++)
	{
		printf("%c", plaintext[i]);
		group[15] = (i + 1) * 8;          //长度是二进制位数		
	}
	/*分组填补*/
	printf("\n\n0x00 正在分组…………\n****************************");
	DevideToGroup(plaintext, group, 7);
	/*从w消息分组中导出*/
	GetExtraMessage(group);
	/*80次步函数*/
	printf("\n0x01 SHA-1加密中…………\n****************************\n");
	for (t = 0; t < 80; t++)
	{
		StepFunction(group, t);
		if (!((t + 1) % 20)) printf("\n");
	}
	/*密文组合*/
	printf("\n0x02 hash值组合中…………\n****************************\n");
	CombineCipher(cipher);
	/*密文输出*/
	printf("\n0x03 SHA-1加密成功！！！\n****************************\nHash：");
	for (j = 0; j <= 4; j++) printf("%08X", cipher[j]);
	printf("\n");
	system("pause");
	return 0;
}